home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Messaging / DfltAcs.cpp next >
Encoding:
Text File  |  1996-08-28  |  55.6 KB  |  1,886 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DfltAcs.cpp
  3.  
  4.     Contains:    Implementation of Mac specific default accessors and handlers.
  5.  
  6.     Owned by:    Jon Pugh
  7.  
  8.     Copyright:    © 1995-96 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <3>     6/20/96    JP        1300215: Check for null iterators
  13.          <2>      6/4/96    EL        1335851: Release string from GetEditor.
  14.         <57>    25/09/95    NP        1979071: Check results of operator new.
  15.         <56>     9/12/95    JP        1280292 & 1283803: Add Part to Send
  16.         <55>     9/11/95    JP        1269048 & 1283405: Use ODGetComments
  17.         <54>     9/11/95    NP        1272294: Messaging code cleanup.
  18.         <53>     8/25/95    JP        1262410: Comments part to frame fallout
  19.         <52>     8/23/95    NP        1276287: Move constant kODAppShell.
  20.         <51>     8/22/95    eeh        1230007: refbal-inspired cleanup
  21.         <50>     8/16/95    eeh        1276765: mostly formatting
  22.         <49>      8/1/95    eeh        1265319: refcount cleanup
  23.         <48>     7/27/95    DM        #1270320: mem leaks: use Temp Objs in
  24.                                     GetPartFromNULL
  25.         <47>     7/27/95    eeh        1243351: handle pIndex property
  26.         <46>     7/21/95    eeh        1262143: call ODDisposeAppleEvent
  27.         <45>     7/18/95    eeh        1262143: memory leaks; 1267932: SOM call on
  28.                                     disposed object
  29.         <44>      7/5/95    NP        1265196: Wrap CreateEmbeddedFramesIterator
  30.                                     call with exception handling.
  31.         <43>      7/5/95    NP        1265125: Initialize local variable.
  32.         <42>      7/3/95    eeh        1264701: remove WARN; shouldn't be there
  33.                                     anyway
  34.         <41>     6/30/95    JP        Refcounting foo
  35.         <40>     6/29/95    DM        1242642 BB: refcounting: release parent
  36.                                     frame in HandleGetDataInternal()
  37.         <39>     6/28/95    eeh        1262143: dispose AEDescs
  38.         <38>     6/20/95    NP        1260389: Fix DrawPart's count proc
  39.         <37>     6/19/95    eeh        1246443: add PartFrameFromStandardPartToken
  40.                                     etc.
  41.         <36>     6/13/95    JP        Use GetDefaultRootFrameToSwapTo in
  42.                                     GetPartFromNULL
  43.         <35>      6/7/95    eeh        1251403: various refcount changes
  44.         <34>     5/26/95    TJ        Removed contextInfo, and refrences to it.
  45.         <33>     5/26/95    RR        #1251403: Multithreading naming support
  46.         <32>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  47.         <31>     5/22/95    eeh        1250831: getdata on part returns objspec
  48.         <30>     5/21/95    NP        1248898: GetUserToken, ODDescToAEDesc, etc.
  49.                                     recipe change.
  50.         <29>     5/18/95    eeh        1250061: make CountEmbeddedFrames
  51.                                     non-static
  52.         <28>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  53.                                     refcount
  54.         <27>     5/12/95    NP        1237955: Just added a comment here,
  55.                                     actually.
  56.         <26>     5/10/95    JP        1242258: ODSetStationery uses frame instead
  57.                                     of part
  58.         <25>      5/4/95    JP        1238246, 1223529: Change name & icon of
  59.                                     file if root part
  60.         <24>      5/4/95    eeh        1246024: initialize ODFrame* in
  61.                                     HandleSetData
  62.         <23>      5/3/95    NP        1211084: Remove 5$
  63.         <22>     4/29/95    TÇ        1244815 BB: Default Accessors return mod
  64.                                     date when asked for create date
  65.         <21>     4/28/95    eeh        (for eeh) 1243352: implemented GetData for
  66.                                     pContainer
  67.         <20>     4/27/95    TÇ        1223529 BB: ODSetPOName and ODSetIconFamily
  68.                                     should tweak file in root part case (Did
  69.                                     name piece)
  70.         <19>     4/25/95    NP        1186795, 1237220, 1240571: Fixed whose
  71.                                     clauses by allowing swapping in count proc.
  72.         <18>     4/25/95    JP        1192027, 1238519: Added properties and
  73.                                     fixed icon & category
  74.         <17>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  75.                                     should take Environment* and SU* when
  76.                                     possible
  77.         <16>     4/14/95    NP        1239651: Include SEPriv.h. Private
  78.                                     constants were moved around.
  79.         <15>      4/7/95    eeh        1236842: added TrySwapToRootPart
  80.         <14>      4/7/95    eeh        1233878: fixed memory leak
  81.         <13>     3/24/95    eeh        1230185: check for null results and errors
  82.         <12>     3/21/95    JP        1192027: Include ODRgstry & change some
  83.                                     constant names
  84.         <11>     3/20/95    NP        1225985: Change API of CreateSwapToken.
  85.         <10>     3/15/95    eeh        1227456: swap when root part should be
  86.                                     equivalent to the document
  87.          <9>     3/13/95    NP        1223764: CreateSwapToken should take an
  88.                                     ODFrame* parameter. Add frame param to
  89.                                     DEFAULT_ACCESSOR_PARAMS.
  90.          <8>      3/2/95    eeh        1214783: finish work on lists
  91.          <7>     2/22/95    eeh        1214783: work on lists; 1222901:
  92.                                     StandardPartToken
  93.          <6>     2/21/95    eeh        1214783: work on lists and on getting by ID
  94.                                     and name
  95.          <5>     2/13/95    eeh        1214783: more work on Get/SetData handlers
  96.          <4>      2/3/95    eeh        1217393: use new ODDesc etc; 1214783:
  97.                                     implement Get/SetData handlers for
  98.                                     part/frame info
  99.          <3>     1/27/95    NP        1213948: Fix object accessors and event
  100.                                     handlers.
  101.          <2>     1/25/95    eeh        1214783: more implementation
  102.          <1>      1/18/95    eeh        first checked in
  103.  
  104.     To Do:
  105.     In Progress:
  106.         
  107. */
  108.  
  109.  
  110. #ifndef _DFLTACS_
  111. #include <DfltAcs.h>
  112. #endif
  113.  
  114. #ifndef _INFOUTIL_
  115. #include <InfoUtil.h>
  116. #endif
  117.  
  118. #ifndef _ODDESUTL_
  119. #include <ODDesUtl.h>
  120. #endif
  121.  
  122. #ifndef _EDITRSET_
  123. #include "EditrSet.h"
  124. #endif
  125.  
  126. #ifndef SOM_ODAppleEvent_xh
  127. #include "ODAplEvt.xh"
  128. #endif
  129.  
  130. #ifndef SOM_ODAddressDesc_xh
  131. #include "ODAdrDes.xh"
  132. #endif
  133.  
  134. #ifndef SOM_ODOSLToken_xh
  135. #include "ODOSLTkn.xh"
  136. #endif
  137.  
  138. #ifndef SOM_ODPart_xh
  139. #include <Part.xh>
  140. #endif
  141.  
  142. #ifndef SOM_ODPartWrapper_xh
  143. #include <PartWrap.xh>
  144. #endif
  145.  
  146. #ifndef __AEPACKOBJECT__
  147. #include <AEPackObject.h>
  148. #endif
  149.  
  150. #ifndef _BNDNSUTL_
  151. #include <BndNSUtl.h>
  152. #endif
  153.  
  154. #ifndef SOM_ODEmbeddedFramesIterator_xh
  155. #include <EmbFrItr.xh>
  156. #endif
  157.  
  158. #ifndef _SIHELPER_
  159. #include <SIHelper.h>
  160. #endif
  161.  
  162. #ifndef _SEUTILS_
  163. #include <SEUtils.h>
  164. #endif
  165.  
  166. #ifndef _SEPRIV_
  167. #include "SEPriv.h"
  168. #endif
  169.  
  170. #ifndef _BARRAY_
  171. #include "BArray.h"
  172. #endif
  173.  
  174. #ifndef _TEMPOBJ_
  175. #include "TempObj.h"
  176. #endif
  177.  
  178. #ifndef SOM_DefaultAccessorSI_xh
  179. #include <MssgSI.xh>
  180. #endif
  181.  
  182. #ifndef SOM_ODNameResolver_xh
  183. #include <NamRslvr.xh>
  184. #endif
  185.  
  186. #ifndef SOM_ODMessageInterface_xh
  187. #include <MssgIntf.xh>
  188. #endif
  189.  
  190. #ifndef SOM_ODWindowState_xh
  191. #include <WinStat.xh>
  192. #endif
  193.  
  194. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  195. #include <StdDefs.xh>
  196. #endif
  197.  
  198. #ifndef __AEOBJECTS__
  199. #include <AEObjects.h>
  200. #endif
  201.  
  202. #ifndef __AEREGISTRY__
  203. #include <AERegistry.h>
  204. #endif
  205.  
  206. #ifndef __OSA__
  207. #include <OSA.h>
  208. #endif
  209.  
  210. #ifndef SOM_Module_OpenDoc_ODRegistry_defined
  211. #include "ODRgstry.xh"
  212. #endif
  213.  
  214. #ifndef __ICONS__
  215. #include <Icons.h>
  216. #endif
  217.  
  218. #pragma segment DefaultAccessors
  219.  
  220. //==============================================================================
  221. // typedefs
  222. //==============================================================================
  223.  
  224. typedef ODError (*InternalHandler)(    Environment *ev,
  225.                                 ODPart* thePart,
  226.                                 ODAppleEvent* message,
  227.                                 ODAppleEvent* reply,
  228.                                 ODSession* session,
  229.                                 AEDesc* directParam,
  230.                                 ODFrame*    frame);
  231.  
  232. //==============================================================================
  233. // Function prototypes
  234. //==============================================================================
  235.  
  236. static void GetDirectParam(ODSession* session, ODAppleEvent* message,
  237.         AEDesc* evtDp);
  238.  
  239. // WE SHOULD AT LEAST HAVE THIS IN A PRIVATE SHARED HEADER.
  240. extern ODFrame* FrameFromContext(OSLContext* context);    // <eeh> ask Nick
  241. static DescType ViewTypetoViewEnum( Environment *ev, ODSession* session,
  242.         ODTypeToken viewType );
  243. static ODTypeToken GetViewTypeFromEnum( Environment *ev, ODSession* session,
  244.         DescType viewEnum );
  245. static ODIText* ITextFromIntlDesc( AEDesc* desc );
  246. static ODError GetEditorFromString(Environment* ev, ODEditor* editor, AEDesc* desc, ODPart* part,
  247.         ODNameSpaceManager* nsm );
  248. static ODIconFamily IfamToIconSuite(AERecord* ifam);
  249. static ODError IconSuiteToIfam( Handle iconSuite, AEDesc* result );
  250. static OSErr CreateObjSpecForFrame( Environment *ev, ODFrame* frame,
  251.         AEDesc* result );
  252. static void AddODOSLTokenToList( ODOSLToken* newToken, ODUShort index,
  253.         AEDesc* list );
  254. static ODOSLToken* DescToODOSLToken( Environment* ev, ODNameResolver* resolver,
  255.         AEDesc* frameDesc, ODOSLToken* tokenToCopy );
  256. //static ODError CreateListInValue( Environment* ev, ODNameResolver* resolver,
  257. //        ODOSLToken* value, AEDesc* list );
  258. extern void NewODToken(ODNameResolver* me, ODOSLToken* openDocToken,
  259.         ODPart* part, OSLToken* newToken);
  260. static ODError HandleEventsForList( Environment *ev,
  261.                                 ODPart* thePart,
  262.                                 ODAppleEvent* message,
  263.                                 ODRecord* reply,
  264.                                 ODSession* session,
  265.                                 AERecord* realToken,
  266.                                 InternalHandler handler );
  267. static ODError HandleGetDataInternal(    Environment *ev, ODPart* thePart,
  268.         ODAppleEvent* message, ODAppleEvent* reply, ODSession* session,
  269.         AEDesc* directParam, ODFrame* frame );
  270. static ODError HandleSetDataInternal(    Environment *ev, ODPart* thePart,
  271.         ODAppleEvent* message, ODAppleEvent* reply, ODSession* session,
  272.         AEDesc* directParam, ODFrame* frame );
  273. static void PutFrameInValue( Environment* ev, ODNameResolver* resolver,
  274.         ODOSLToken* value, ODFrame* frame );
  275. static ODBoolean ITextEqual( ODIText* name1, ODIText* name2 );
  276. static ODFrame* AcquireFrameWithName( Environment* ev, ODFrame* startFrame,
  277.         ODIText* name );
  278. static ODBoolean PartIsContained( Environment* ev, ODFrame* testee,
  279.     ODFrame* container );
  280. static OSErr IndexForFrame( Environment *ev, ODFrame* frame, ODULong* result );
  281. static ODError SwapToRootPart( Environment *ev, ODSession* session,
  282.         ODOSLToken* value);
  283. static ODPersistentObjectID GetIDForFrame( Environment* ev, ODFrame* frame );
  284. // static void CopyNonDPParams( ODAppleEvent* message, ODAppleEvent* newMessage );
  285.  
  286. void ODDuplicateEvent( ODAppleEvent* scrDesc, ODAppleEvent** destDesc );
  287. void ODPutParamDesc( ODAppleEvent* odaevt, DescType keyword, AEDesc* desc );
  288. void ODPutParamDesc( ODAppleEvent* odaevt, DescType keyword, ODDesc* desc );
  289. void ODGetParamDesc( ODAppleEvent* odaevt, DescType keyword, DescType typeSought,
  290.         AEDesc* desc );
  291. void ODGetParamDesc( ODAppleEvent* odaevt, DescType keyword, DescType typeSought,
  292.         ODDesc** desc );
  293. void ODPutAttributeDesc( ODAppleEvent* message, AEKeyword key, ODDesc* desc );
  294. void ODGetAttributePtr( ODAppleEvent *appleEvent, AEKeyword theAEKeyword,
  295.         DescType desiredType, DescType *typeCode, void *dataPtr,
  296.         Size maximumSize, Size *actualSize);
  297.  
  298. #if ODDebug
  299. void PukeIfFrameNULL( ODFrame* frame );
  300. #else
  301. #define PukeIfFrameNULL(frame)
  302. #endif
  303.  
  304. //==============================================================================
  305. // Object Accessor functions
  306. //==============================================================================
  307.  
  308. //------------------------------------------------------------------------------
  309. // GetWildcardFromPart
  310. //------------------------------------------------------------------------------
  311.  
  312. ODError GetWildcardFromPart(DEFAULT_ACCESSOR_PARAMS)
  313. {    
  314.     ODError result;
  315.     TRY
  316.         ODPart* part;
  317.         ODFrame* frame;
  318.         PartFrameFromStandardPartToken( container, &part, &frame );
  319.         ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  320.         session->GetNameResolver(ev)->CreateSwapToken(ev, value, part, frame );
  321.         result = noErr;
  322.     CATCH_ALL
  323.         result = errAENoSuchObject;
  324.     ENDTRY
  325.     return result;
  326. }
  327.  
  328. //------------------------------------------------------------------------------
  329. // TrySwapToRootPart
  330. //------------------------------------------------------------------------------
  331.  
  332. ODError TrySwapToRootPart(DEFAULT_ACCESSOR_PARAMS)
  333. {
  334.     WASSERT( !scriptlessPart );
  335.     return SwapToRootPart( ev, session, value );
  336. }
  337.  
  338. //------------------------------------------------------------------------------
  339. // GetPropFromNULL
  340. //------------------------------------------------------------------------------
  341.  
  342. ODError GetPropFromNULL(DEFAULT_ACCESSOR_PARAMS)
  343. {
  344.     ODError result = noErr ;
  345.     ODNameResolver* resolver = session->GetNameResolver(ev);
  346.  
  347.     TRY
  348.         if ( (!resolver->IsODToken( ev, value )) || (form != formPropertyID) )
  349.             THROW( errAENoSuchObject );
  350.     
  351.         if ( scriptlessPart == kODAppShell )
  352.             return SwapToRootPart( ev, session, value );
  353.  
  354.         AEDesc realSelData;
  355.         THROW_IF_ERROR( ODDescToAEDesc(selectionData, &realSelData ));
  356.         TempAEDesc tmpDesc(&realSelData);
  357.     
  358.         switch ( FIRSTBYTESFROMHANDLE(realSelData.dataHandle, DescType) )
  359.         {    
  360.             case pName:
  361.             case pComment:
  362.             case pAuthor:
  363.             case pKind:
  364.             case pEditorName:
  365.             case pBundled:
  366.             case pStationery:
  367.             case pShowLinks:
  368.             case pASCreationDate:
  369.             case pASModificationDate:
  370.             case pSize:
  371.             case pUniqueID:
  372.             case pIcon:
  373.             case pViewType:
  374.             case pContainer:
  375.             case pCategory:
  376.             case pClass:
  377.             case pDefaultType:
  378.             case pBestType:
  379.             case pIndex:
  380.                 break;
  381.             default:
  382.                 result = errAENoSuchObject;
  383.         }
  384.     
  385.         if ( !result )
  386.         {
  387.             ODDesc* userTokenAsODDesc = resolver->GetUserToken(ev, value);
  388.             THROW_IF_ERROR( AEDescToODDesc( &realSelData, userTokenAsODDesc ));
  389.             userTokenAsODDesc->SetDescType(ev, cProperty);
  390.         }
  391.     
  392.     CATCH_ALL
  393.         result = ErrorCode();
  394.     ENDTRY
  395.  
  396. //    AEDisposeDesc( &realSelData );
  397.     return result;
  398. }
  399.  
  400. //------------------------------------------------------------------------------
  401. // GetWildcardFromList
  402. //------------------------------------------------------------------------------
  403.  
  404. ODError GetWildcardFromList(DEFAULT_ACCESSOR_PARAMS)
  405. {
  406.     ODNameResolver* resolver = session->GetNameResolver(ev);
  407.     ODError error = noErr;
  408.  
  409.     AEDesc newList;
  410.     THROW_IF_ERROR( AECreateList( kODNULL, 0, kODFalse, &newList ) );
  411.     TempAEDesc tmpList( &newList );
  412. //    THROW_IF_ERROR( CreateListInValue( ev, resolver, value,
  413. //            &newList ) );
  414.  
  415.     ODSLong count;
  416.     THROW_IF_ERROR( AECountItems( container, &count ) );
  417.     for ( ODUShort index = 1; index <= count; ++index )
  418.     {
  419.         AEDesc        oneContainer;
  420.         DescType    containerDescType;
  421.  
  422.         THROW_IF_ERROR( AEGetNthDesc( container, index, typeWildCard,
  423.                 &containerDescType, &oneContainer ) );
  424.         TempAEDesc tmpDesc( &oneContainer );
  425.  
  426.         ODOSLToken* containerWrapper = new ODOSLToken();
  427.         THROW_IF_NULL(containerWrapper);
  428.         TempODObject tmpObj(containerWrapper);
  429.         containerWrapper->InitODOSLToken(ev);
  430.         THROW_IF_ERROR( AEDescToODDesc( &oneContainer, containerWrapper ) );
  431.         
  432.         if ( !resolver->IsODToken( ev, containerWrapper ) )
  433.         {
  434.             error = errAENoSuchObject;
  435.             break;
  436.         }
  437.  
  438.         ODOSLToken* newValue = value->DuplicateODOSLToken(ev);
  439.         TempODObject tmpObj2(newValue);
  440.         
  441.         resolver->CallObjectAccessor(ev, scriptlessPart, desiredClass,
  442.                 containerWrapper, containerClass, form, selectionData,
  443.                 newValue );
  444.  
  445.         AddODOSLTokenToList( newValue, index, &newList );
  446.  
  447. //        ODDeleteObject(newValue);
  448. //        ODDeleteObject(containerWrapper);
  449.  
  450. //        (void)AEDisposeDesc( &oneContainer );
  451.     }
  452.  
  453.     ODDesc* userODToken = resolver->GetUserToken(ev, value);
  454.     AEDescToODDesc(&newList, userODToken);
  455. //    (void)AEDisposeDesc( &newList );
  456.  
  457.     return error;
  458. }    // GetWildcardFromList()
  459.  
  460. //------------------------------------------------------------------------------
  461. // GetPartFromNULL
  462. //------------------------------------------------------------------------------
  463.  
  464. ODError GetPartFromNULL(DEFAULT_ACCESSOR_PARAMS)
  465. {
  466.     ODUnused(desiredClass);
  467.     ODUnused(container);
  468.     ODUnused(containerClass);
  469.  
  470.     ODNameResolver*        resolver = session->GetNameResolver(ev);
  471.     ODUShort             i;
  472.     ODError                error = noErr;
  473.  
  474.     if( !resolver->IsODToken( ev, value ) )
  475.         return errAENoSuchObject;
  476.     
  477.     AEDesc coercedSelData = NULL_DESCRIPTOR_DEFINITION;
  478.  
  479.     TRY
  480.  
  481.     ODFrame* containingFrame;
  482.     ODPart* ignorePart;
  483.     resolver->GetContextFromToken(ev, value, &ignorePart, &containingFrame);
  484.  
  485. //    PRINT("containingFrame = %ld\n", containingFrame);
  486.     AEDesc realSelData;
  487.     THROW_IF_ERROR( ODDescToAEDesc(selectionData, &realSelData ));
  488.     TempAEDesc tmpSelData(&realSelData);
  489.  
  490.     switch (form)
  491.     {
  492.         case formName:
  493.         {
  494.             TempODFrame resultFrame = kODNULL;
  495.             THROW_IF_ERROR( AECoerceDesc( &realSelData, typeIntlText,
  496.                     &coercedSelData ) );
  497.             TempODIText name = ITextFromIntlDesc( &coercedSelData );
  498.             AEDisposeDesc( &coercedSelData );
  499.  
  500.             if ( !containingFrame )
  501.             {
  502.                 containingFrame =  GetDefaultRootFrameToSwapTo(ev, session);
  503. //                ODWindow* odWindow = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
  504. //                containingFrame = odWindow->GetRootFrame(ev);
  505. //                ODReleaseObject(ev, odWindow);
  506.                 TempODIText rootName = ODGetPartName(ev, containingFrame,
  507.                         kODNULL);
  508.                 if ( ITextEqual( rootName, name ) )
  509.                     resultFrame = containingFrame ;
  510.             }
  511.             if ( !resultFrame )
  512.                 resultFrame = AcquireFrameWithName( ev, containingFrame, name );
  513.             PutFrameInValue( ev, resolver, value, resultFrame );
  514. //            ODReleaseObject(ev, resultFrame);
  515.             break;
  516.         }
  517.             
  518.         case formUniqueID:
  519.         {
  520.             THROW_IF_ERROR( AECoerceDesc( &realSelData, typeLongInteger,
  521.                     &coercedSelData ) );
  522.             ODPersistentObjectID objectID = FIRSTBYTESFROMHANDLE(
  523.                     coercedSelData.dataHandle, ODPersistentObjectID );
  524.             AEDisposeDesc( &coercedSelData );
  525.  
  526.             ODStorageUnit* su = (containingFrame ? containingFrame : 
  527.                     GetDefaultRootFrameToSwapTo(ev, session))->
  528.                     GetStorageUnit(ev);
  529.             WASSERT(su);
  530.             ODDraft* draft = su->GetDraft(ev);
  531.             ODObjectType objectType;
  532.             TempODFrame thisFrame = (ODFrame*)draft->AcquirePersistentObject(
  533.                     ev, objectID, &objectType);
  534.             TempODObjectType tempObjectType(objectType); // ensure deletion
  535.             
  536.             if ( !thisFrame || (strcmp( kODFrameObject, objectType ) != 0)
  537.                     || (!PartIsContained( ev, thisFrame, containingFrame )) )
  538.                 THROW(errAENoSuchObject);    // $$$$$ This could leak a reference?
  539.             PutFrameInValue( ev, resolver, value, thisFrame );
  540. //            ODReleaseObject(ev, tmpFrame);
  541.         }    break;
  542.  
  543.         case formAbsolutePosition:
  544.         {
  545.             // if the containing part is null, we substitute the root part
  546.             // by doing a swap.  Note that we do this *only* in the case of
  547.             // formAbsolutePosition, because in the others we need to avoid
  548.             // implicit "root part of root part" object specifiers.
  549.             
  550.             if ( scriptlessPart == kODAppShell )
  551.             {
  552.                 error = SwapToRootPart( ev, session, value );
  553.                 break;
  554.             }
  555.  
  556.             // Are we being asked for an indexed part
  557.             // or for all parts?
  558.             ODSLong theIndex;
  559.             ODBoolean allFlag;
  560.             ODBoolean zeroFlag;
  561.  
  562.             ODSLong partCount = CountEmbeddedParts(ev, scriptlessPart);
  563.             error = DecodeOrdinal( realSelData, (long)partCount, 
  564.                             (long*)&theIndex, (Boolean*)&allFlag, (Boolean*)&zeroFlag);
  565.             THROW_IF_ERROR(error);
  566.             
  567.             ODEmbeddedFramesIterator* iter = kODNULL;
  568.             if ( scriptlessPart != kODAppShell ) {
  569.                 iter = scriptlessPart->CreateEmbeddedFramesIterator(ev, kODNULL);
  570.                 if (iter == kODNULL)
  571.                     THROW(kODErrCannotEmbed);
  572.             }
  573.             if ( allFlag )
  574.             {
  575.                 AEDesc listOfTokens;
  576.                 THROW_IF_ERROR( AECreateList( kODNULL, 0, kODFalse,
  577.                         &listOfTokens ) );
  578.                 TempAEDesc tmpDesc( &listOfTokens );
  579. //                error = CreateListInValue( ev, resolver, value, &listOfTokens );
  580. //                THROW_IF_ERROR(error);
  581.  
  582.                 // Get theEmbeddedPart number theIndex
  583.                 for (containingFrame = iter->First(ev), i=1; iter->IsNotComplete(ev);
  584.                         containingFrame = iter->Next(ev), i++)
  585.                 {    
  586.                     if (containingFrame)
  587.                     {
  588.                         AEDesc frameDesc;
  589.                         TempODPart    part = containingFrame->AcquirePart(ev);
  590.                         THROW_IF_ERROR( CreateStandardPartToken(containingFrame,
  591.                                 part, &frameDesc ) );
  592.  
  593.                         ODOSLToken* newValue = DescToODOSLToken(ev,
  594.                                 resolver, &frameDesc, value );
  595.                         (void)AEDisposeDesc(&frameDesc);
  596.                         AddODOSLTokenToList( newValue, i, &listOfTokens );
  597.                         ODDeleteObject( newValue );
  598.                     }
  599.                 }
  600.  
  601.                 ODDesc*    userTokenODDesc = resolver->GetUserToken( ev, value );
  602.                 THROW_IF_ERROR(AEDescToODDesc(&listOfTokens, userTokenODDesc));
  603.  
  604. //                AEDisposeDesc(&listOfTokens);
  605.             }
  606.             else
  607.             {
  608.                 // Get theEmbeddedPart number theIndex
  609.                 for (containingFrame = iter->First(ev), i=1; iter->IsNotComplete(ev);
  610.                         containingFrame = iter->Next(ev), i++)
  611.                 {    
  612.                     if (i == theIndex)
  613.                         break;
  614.                 }
  615.                 
  616.                 PutFrameInValue( ev, resolver, value, containingFrame );
  617.             }
  618.             ODDeleteObject(iter);
  619.             break;
  620.         }
  621.         default:
  622.             THROW(errAENoSuchObject);
  623.             break;
  624.     }
  625.         
  626.     
  627.     CATCH_ALL
  628.     error = ErrorCode();
  629.     ENDTRY
  630.     
  631. //    (void)AEDisposeDesc( &realSelData );
  632.     return error;
  633. }
  634.  
  635. //==============================================================================
  636. // Event Handler functions
  637. //==============================================================================
  638.  
  639. //------------------------------------------------------------------------------
  640. // HandleGetData
  641. //------------------------------------------------------------------------------
  642.  
  643. ODError HandleGetData(    Environment *ev,
  644.                         ODPart* thePart,
  645.                         ODAppleEvent* message,
  646.                         ODAppleEvent* reply,
  647.                         ODSession* session)
  648. {
  649.     ODError            error = noErr;
  650.     ODNameResolver*    resolver = session->GetNameResolver(ev);
  651.  
  652.     OSLToken evtDp;
  653.     GetDirectParam( session, message, &evtDp );
  654.     TempAEDesc tmpDesc(&evtDp);
  655.  
  656.     ODOSLToken* tmpWrapper = new ODOSLToken();
  657.     THROW_IF_NULL(tmpWrapper);
  658.     TempODObject tmpObj(tmpWrapper);
  659.     tmpWrapper->InitODOSLToken(ev);
  660.     THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  661.  
  662.     ODPart* ignorePart;
  663.     ODFrame* frame;
  664.     resolver->GetContextFromToken(ev, tmpWrapper, &ignorePart, &frame);
  665.  
  666.     ODDesc* myToken;
  667.     myToken = resolver->GetUserToken(ev, tmpWrapper);
  668.     AEDesc realToken;
  669.     THROW_IF_ERROR( ODDescToAEDesc(myToken, &realToken) );
  670.  
  671.     error = HandleGetDataInternal( ev, thePart, message, reply,
  672.             session, &realToken, frame );
  673.  
  674.     AEDisposeDesc(&realToken);
  675. //    AEDisposeDesc(&evtDp);
  676.  
  677. //    ODDeleteObject(tmpWrapper);
  678.     return error;
  679. }
  680.  
  681. //------------------------------------------------------------------------------
  682. // PukeIfFrameNULL
  683. //------------------------------------------------------------------------------
  684.  
  685. #if ODDebug
  686. void PukeIfFrameNULL( ODFrame* frame )
  687. {
  688.     if ( !frame )
  689.     {
  690.         WARN( "frame is null; throwing errAEEventNotHandled." );
  691.         THROW( errAEEventNotHandled );
  692.     }
  693. }
  694. #endif
  695.  
  696. ODError HandleGetDataInternal(    Environment *ev,
  697.                                 ODPart* thePart,
  698.                                 ODAppleEvent* message,
  699.                                 ODAppleEvent* reply,
  700.                                 ODSession* session,
  701.                                 AEDesc* directParam,
  702.                                 ODFrame*    frame)
  703. {
  704.     ODError err = noErr;
  705.  
  706.     if ( directParam->descriptorType == typeAEList )
  707.     {
  708.         err = HandleEventsForList( ev, thePart, message, reply,
  709.                 session, directParam, HandleGetDataInternal );
  710.     }
  711.     else
  712.     {
  713.         if ( !thePart )
  714.             return errAEEventNotHandled;
  715.  
  716.         AEDesc result = NULL_DESCRIPTOR_DEFINITION;
  717.  
  718.         // find out what type was requested
  719.         // e.g. get foo as alias
  720.         DescType    desiredType, theType;
  721.         long        theSize;
  722.         AppleEvent    theMessage;
  723.         THROW_IF_ERROR( ODDescToAEDesc(message, &theMessage) );
  724.         err = AEGetParamPtr( &theMessage, keyAERequestedType, typeType,
  725.                 &theType, &desiredType, sizeof(desiredType), &theSize );
  726.         ODDisposeAppleEvent(&theMessage);
  727.         if ( err != noErr )
  728.             desiredType = typeWildCard;
  729.  
  730.         switch( directParam->descriptorType )
  731.         {
  732.             case cPart:
  733.                 err = CreateObjSpecForFrame( ev,
  734.                         FrameFromStandardPartToken(directParam), &result );
  735.                 break;
  736.  
  737.             case cProperty:
  738.             {
  739.                 ODBoolean boolResult;
  740.                 ODIText* itext = kODNULL;
  741.         
  742.                 ODStorageUnit* partSU = ODGetSUFromPstObj(ev, thePart);
  743.                 
  744.                 DescType property = FIRSTBYTESFROMHANDLE( directParam->dataHandle,
  745.                         DescType );
  746.                 
  747.                 switch( property )
  748.                 {
  749.                     // text properties
  750.                     case pName:
  751.                     case pComment:
  752.                     case pAuthor:
  753.                     case pKind:
  754.                     case pEditorName:
  755.                     case pCategory:
  756.                     {
  757.                         ODBoolean okToDispose = kODTrue;
  758.                         if ( property == pName )
  759.                             itext = ODGetPartName(ev, frame, kODNULL );
  760.                         else if ( property == pComment )
  761.                         {
  762.                             itext = ODGetComments(ev, frame, kODNULL );
  763.                             if ( !itext )
  764.                             {
  765.                                 // script and language code don't matter here; stripped below
  766.                                 itext = CreateITextCString( 0, 0, "" );
  767.                                 okToDispose = kODTrue;
  768.                             }
  769.                         }
  770.                         else if ( property == pCategory )
  771.                             itext = ODGetCategory(ev, thePart, session->GetNameSpaceManager(ev) );
  772.                         else if ( property == pAuthor )
  773.                             itext = ODGetModifiedBy(ev, partSU, kODNULL );
  774.                         else if ( property == pKind )
  775.                         {
  776.                             ODType theType = ODGetKind(ev, thePart );
  777.                             okToDispose = !GetUserKindFromKind(
  778.                                     session->GetNameSpaceManager(ev), theType, &itext );
  779.                         }
  780.                         else if ( property == pEditorName )
  781.                         {
  782.                             TempODEditor editor = ((ODPartWrapper*)thePart)->GetEditor(ev);
  783.                             okToDispose = !GetUserEditorFromEditor(
  784.                                     session->GetNameSpaceManager(ev), editor, &itext );
  785.                         }
  786.             
  787.                         if ( itext )
  788.                         {
  789.                             err = AECreateDesc( typeChar, GetITextPtr( itext ),
  790.                                     GetITextStringLength( itext ), &result );
  791.                             if ( okToDispose )
  792.                                 DisposeIText(itext);
  793.                         }
  794.                         else
  795.                             err = errAEEventNotHandled;
  796.                         break;
  797.                     }
  798.                     
  799.                     // type properties
  800.                     case pClass:
  801.                     case pDefaultType:
  802.                     case pBestType:
  803.                     {
  804.                         DescType theType = cObjectSpecifier;
  805.                         if (property == pClass)
  806.                             theType = cPart;
  807.                         err = AECreateDesc(typeType, &theType, sizeof(theType), &result);
  808.                         break;
  809.                     }
  810.                     
  811.                     // boolean properties
  812.                     case pBundled:
  813.                     case pStationery:
  814.                     case pShowLinks:
  815.                     {
  816.                         if ( property == pBundled )
  817.                         {
  818.                             PukeIfFrameNULL( frame );
  819.                             ASSERT_FRAME_MATCHES_PART( ev, frame, thePart );
  820.                             boolResult = frame->IsFrozen(ev);
  821.                         }
  822.                         else if ( property == pStationery )
  823.                             boolResult = ODGetIsStationery(ev, frame);
  824.                         else // if ( property == pShowLinks )
  825.                         {
  826.                             PukeIfFrameNULL( frame );
  827.                             TempODWindow window = frame->AcquireWindow(ev);
  828.                             boolResult = window->ShouldShowLinks(ev);
  829. //                            ODReleaseObject( ev, window );
  830.                         }
  831.                         
  832.                         err = AECreateDesc(typeBoolean, &boolResult, sizeof(boolResult),
  833.                                 &result );
  834.                         break;
  835.                     }
  836.                     
  837.                     // date properties
  838.                     case pASCreationDate:
  839.                     case pASModificationDate:
  840.                     {
  841.                         long theDate[2];
  842.                         
  843.                         theDate[0] = 0;
  844.                         if ( property == pASCreationDate )
  845.                             theDate[1] = ODGetCreationDate(ev, partSU);
  846.                         else // if ( property == pASModificationDate )
  847.                             theDate[1] = ODGetModificationDate(ev, partSU);
  848.                         err = AECreateDesc(typeLongDateTime, &theDate, sizeof(theDate), &result);
  849.                         break;
  850.                     }
  851.                     
  852.                     case pSize:
  853.                     {
  854.                         ODULong longResult = ODGetPOSize(ev, thePart );
  855.                         err = AECreateDesc(typeLongInteger, &longResult,
  856.                                 sizeof(longResult), &result );
  857.                         break;
  858.                     }
  859.                     
  860.                     case pUniqueID:
  861.                     {
  862.                         PukeIfFrameNULL( frame );
  863.                         ODPersistentObjectID id = GetIDForFrame( ev, frame );
  864.                         err = AECreateDesc(typeLongInteger, &id,
  865.                                 sizeof(id), &result );
  866.                         break;
  867.                     }
  868.                     
  869.                     case pIndex:
  870.                         PukeIfFrameNULL( frame );
  871.                         ODULong index;
  872.                         err = IndexForFrame( ev, frame, &index );
  873.                         if ( err == noErr )
  874.                             err = AECreateDesc( typeLongInteger, &index,
  875.                                     sizeof(index), &result );
  876.                         break;
  877.  
  878.                     case pIcon:
  879.                     {
  880.                         ODIconFamily iconFamily = ODGetIconFamily(ev, frame );
  881.                         err = IconSuiteToIfam( iconFamily, &result );
  882.                         break;
  883.                     }
  884.             
  885.                     case pViewType:
  886.                     {
  887.                         PukeIfFrameNULL( frame );
  888.                         DescType type = ViewTypetoViewEnum( ev, session,
  889.                                 frame->GetViewType(ev) ) ;
  890.                         err = AECreateDesc(typeEnumeration, &type,
  891.                                 sizeof(type), &result );
  892.                         break;
  893.                     }
  894.         
  895.                     case pContainer:
  896.                     {
  897.                         PukeIfFrameNULL( frame );
  898.                         { TempODFrame parentFrame = frame->AcquireContainingFrame(ev); // DMc refcount - make temp
  899.                           // DMc - I carefully checked that CreateObjSpecForFrame() does not consume this ref.
  900.                           err = parentFrame ?
  901.                                 CreateObjSpecForFrame(ev, parentFrame, &result)
  902.                                 : errAENoSuchObject;
  903.                         }
  904.                         break;
  905.                     }
  906.                     default:
  907.                         err = errAEEventNotHandled;
  908.                 }
  909.                 break;    // case cProperty:
  910.             }
  911.             default:
  912.                 err = errAEEventNotHandled;
  913.         }
  914.         
  915.         if ( !err )
  916.         {
  917.             if (desiredType != typeWildCard && desiredType != result.descriptorType)
  918.             {
  919.                 AEDesc    newDesc;
  920.                 err = AECoerceDesc(&result, desiredType, &newDesc);
  921.                 if (err != noErr)
  922.                 {
  923.                     // we can't coerce to the desiredType, so we provide a decent
  924.                     // error message and throw the error
  925.                     AppleEvent    replyAsAEDesc;
  926.                     THROW_IF_ERROR( ODDescToAEDesc(reply, &replyAsAEDesc) );
  927.                     THROW_IF_ERROR( AEPutParamPtr(&replyAsAEDesc, kOSAErrorExpectedType, typeType,
  928.                                 &desiredType, sizeof(desiredType)) );
  929.                     THROW_IF_ERROR( AEDescToODDesc(&replyAsAEDesc, reply) );
  930.                     ODDisposeAppleEvent(&replyAsAEDesc);
  931.                     THROW(err);
  932.                 }
  933.                 
  934.             }    
  935.         }
  936.  
  937.         if ( !err )
  938.         {
  939.             ODPutParamDesc( reply, keyDirectObject, &result );
  940.             AEDisposeDesc( &result );
  941.         }
  942.  
  943.     }
  944.     return err;
  945. }    // HandleGetDataInternal
  946.  
  947. //------------------------------------------------------------------------------
  948. // HandleEventsForList
  949. //------------------------------------------------------------------------------
  950.  
  951. static ODError HandleEventsForList( Environment *ev,
  952.                                 ODPart* thePart,
  953.                                 ODAppleEvent* message,
  954.                                 ODRecord* reply,
  955.                                 ODSession* session,
  956.                                 AERecord* realToken,
  957.                                 InternalHandler handler )
  958. {
  959.     ODError err = noErr;
  960.     AERecord fakeReply;
  961.     AERecord listOTokens;
  962.     
  963.     TRY
  964.         if ( reply )
  965.         {
  966.             THROW_IF_ERROR( AECreateList( kODNULL, 0, kODTrue, &fakeReply ) );
  967.             THROW_IF_ERROR( AECreateList( kODNULL, 0, kODFalse, &listOTokens ));
  968.         }
  969.  
  970.         ODSLong count;
  971.         THROW_IF_ERROR( AECountItems( realToken, &count ) );
  972.  
  973.         for ( ODUShort index = 1; index <= count ; ++index )
  974.         {
  975.             AEDesc        oneToken;
  976.             DescType    tokenDescType;
  977.             THROW_IF_ERROR( AEGetNthDesc( realToken, index, typeWildCard,
  978.                     &tokenDescType, &oneToken ) );
  979.             TempAEDesc tmpDesc( &oneToken );
  980.     
  981.             ODMessageInterface* msgIntf = session->GetMessageInterface(ev);
  982.  
  983.             AEEventClass eventClass = (AEEventClass)GetSLongAttrOD(
  984.                     message, keyEventClassAttr);
  985.             AEEventID eventID = (AEEventID)GetSLongAttrOD(
  986.                     message, keyEventIDAttr);
  987.  
  988.             ODAddressDesc* addressDesc;
  989.             msgIntf->CreatePartAddrDesc( ev, &addressDesc, thePart );// <eeh> not the right part <jp> why?  is it now?
  990.             TempODObject tmpObj(addressDesc);
  991.  
  992.             ODAppleEvent* newMessage;
  993.             ODDuplicateEvent( message, &newMessage );
  994.             TempODObject tmpODAEVT(newMessage);
  995.             ODPutAttributeDesc( newMessage, keyAddressAttr, addressDesc );
  996.  
  997.             ODPutParamDesc( newMessage, keyDirectObject, &oneToken );
  998.  
  999.             ODAppleEvent* odreply = new ODAppleEvent();
  1000.             THROW_IF_NULL(odreply);
  1001.             TempODObject tmpObj2(odreply);
  1002.             odreply->InitODAppleEvent(ev);
  1003.             
  1004.             msgIntf->Send( ev, kODNULL, thePart, newMessage, odreply,
  1005.                     kAEWaitReply | kAECanInteract | kAEDontRecord,
  1006.                     kAENormalPriority,
  1007.                     kAEDefaultTimeout );
  1008.  
  1009.             if ( reply )
  1010.             {
  1011.                 AEDesc oneReplyToken;
  1012.                 ODGetParamDesc( odreply, keyDirectObject, typeWildCard,
  1013.                         &oneReplyToken );
  1014.                 THROW_IF_ERROR(AEPutDesc( &listOTokens, index, &oneReplyToken));
  1015.                 AEDisposeDesc( &oneReplyToken );
  1016.             }
  1017. //            ODDeleteObject( odreply );
  1018. //            ODDeleteObject( addressDesc );
  1019. //            ODDeleteObject( newMessage );
  1020. //            AEDisposeDesc( &oneToken );
  1021.         }
  1022.  
  1023.     CATCH_ALL
  1024.         err = ErrorCode();
  1025.     ENDTRY
  1026.         if ( reply )
  1027.         {
  1028.             if ( !err )
  1029.                 ODPutParamDesc( (ODAppleEvent*)reply, keyDirectObject,
  1030.                         &listOTokens );
  1031.             (void)AEDisposeDesc( &listOTokens );
  1032.             (void)AEDisposeDesc( &fakeReply );
  1033.         }
  1034.  
  1035.     return err;
  1036. }
  1037.  
  1038. //------------------------------------------------------------------------------
  1039. // HandleSetData
  1040. //------------------------------------------------------------------------------
  1041.  
  1042. ODError HandleSetData(    Environment *ev,
  1043.                         ODPart* thePart,
  1044.                         ODAppleEvent* message,
  1045.                         ODAppleEvent* reply,
  1046.                         ODSession* session)
  1047. {
  1048.     ODError error = noErr;
  1049.     ODNameResolver* resolver = session->GetNameResolver(ev);
  1050.  
  1051.     AEDesc evtDp;
  1052.     GetDirectParam( session, message, &evtDp );
  1053.  
  1054.     ODOSLToken* tmpWrapper = new ODOSLToken();
  1055.     THROW_IF_NULL(tmpWrapper);
  1056.     TempODObject tmpObj(tmpWrapper);
  1057.     tmpWrapper->InitODOSLToken(ev);
  1058.     THROW_IF_ERROR( AEDescToODDesc(&evtDp, tmpWrapper ) );
  1059.     (void)AEDisposeDesc( &evtDp );
  1060.  
  1061.     if( resolver->IsODToken(ev, tmpWrapper) )
  1062.     {
  1063.         ODDesc* myToken = resolver->GetUserToken(ev, tmpWrapper);
  1064.         AEDesc realToken;
  1065.         THROW_IF_ERROR( ODDescToAEDesc(myToken, &realToken ) );
  1066.         TempAEDesc tmpDesc(&realToken);
  1067.         
  1068.         ODPart* ignorePart;
  1069.         ODFrame* frame;
  1070.         resolver->GetContextFromToken(ev, tmpWrapper, &ignorePart, &frame);
  1071.     
  1072.         error = HandleSetDataInternal( ev, thePart, message, reply,
  1073.                 session, &realToken, frame );
  1074.     
  1075. //        (void)AEDisposeDesc( &realToken );
  1076.     }
  1077.     else
  1078.         error = errAENoSuchObject;
  1079.  
  1080. //    ODDeleteObject(tmpWrapper);
  1081.  
  1082.     return error;
  1083. }
  1084.  
  1085.  
  1086. //------------------------------------------------------------------------------
  1087. // HandleSetDataInternal
  1088. //------------------------------------------------------------------------------
  1089.  
  1090. ODError HandleSetDataInternal( Environment *ev, ODPart* thePart,
  1091.         ODAppleEvent* message, ODAppleEvent* /*reply*/, ODSession* session,
  1092.         AEDesc* directParam, ODFrame* frame )
  1093. {    
  1094.     ODError error = noErr;
  1095.  
  1096.     if ( directParam->descriptorType == typeAEList )
  1097.     {
  1098.         // SetData for lists provided for testing only!  Will be removed before ship
  1099. #if ODDebug
  1100.         error = HandleEventsForList( ev, thePart, message, kODNULL,    // null for reply
  1101.                 session, directParam, HandleSetDataInternal );
  1102. #else
  1103.         // we don't do destructive things on lists.  There's no way to ensure
  1104.         // that all will succeed before beginning, and managing fewer than
  1105.         // all of them is not acceptable.
  1106.         return errAEEventNotHandled;
  1107. #endif
  1108.     }
  1109.     else
  1110.     {
  1111.         if ( directParam->descriptorType != cProperty )
  1112.             return errAENoSuchObject;
  1113.         
  1114. //        ODFrame* frame = session->GetNameResolver(ev)->AcquireContainingFrame(ev);
  1115.     
  1116.         DescType property = FIRSTBYTESFROMHANDLE( directParam->dataHandle,
  1117.                 DescType );
  1118.     
  1119.         AEDesc dataDesc;
  1120.         ODGetParamDesc( message, keyAEData, typeWildCard, &dataDesc );
  1121.         if ( !error )
  1122.         {
  1123.             AEDesc coercedDataDesc;
  1124.             coercedDataDesc.dataHandle = kODNULL;
  1125.             switch( property )
  1126.             {
  1127.                 // read only properties: this is an error
  1128.                 case pAuthor:
  1129.                 case pSize:
  1130.                 case pASCreationDate:
  1131.                 case pASModificationDate:
  1132.                 case pCategory:
  1133.                 case pKind:
  1134.                 case pUniqueID:
  1135.                 case pContainer:
  1136.                 case pIndex:
  1137.                     // <eeh> is there an error for setting r/o properties?
  1138.                     error = errAEEventNotHandled;
  1139.                     break;
  1140.     
  1141.                 case pName:
  1142.                 case pComment:
  1143.                     error = AECoerceDesc( &dataDesc, typeIntlText, &coercedDataDesc );
  1144.                     if ( !error )
  1145.                     {
  1146.                         ODIText* name = ITextFromIntlDesc(&coercedDataDesc);
  1147.                         if ( property == pName )
  1148.                         {
  1149.                             if (!ODSetPartName(ev, frame, name, kAENo))
  1150.                                 error = errAEEventNotHandled;
  1151.                         }
  1152.                         else // if ( property == pComment )
  1153.                             ODSetComments(ev, frame, name );
  1154.     
  1155.                         DisposeIText(name);
  1156.                     }
  1157.                     break;
  1158.                 
  1159.                 case pBundled:
  1160.                 case pStationery:
  1161.                 case pShowLinks:
  1162.                     error = AECoerceDesc( &dataDesc, typeBoolean, &coercedDataDesc );
  1163.                     if ( !error )
  1164.                     {
  1165.                         ODBoolean bool = FIRSTBYTESFROMHANDLE(
  1166.                                 coercedDataDesc.dataHandle,    ODBoolean );
  1167.                         if ( property == pBundled )
  1168.                         {
  1169.                             WASSERT( frame );
  1170.                             ASSERT_FRAME_MATCHES_PART( ev, frame, thePart );
  1171.                             frame->SetFrozen( ev, bool );
  1172.                         }
  1173.                         else if ( property == pStationery )
  1174.                             ODSetIsStationery(ev, frame, bool );
  1175.                         else if ( property == pShowLinks )
  1176.                         {
  1177.                             PukeIfFrameNULL( frame );
  1178.                             SetAllWindowShowLinks(ev, session->GetWindowState(ev), bool);
  1179. //                            TempODWindow window = frame->AcquireWindow(ev);
  1180. //                            window->SetShouldShowLinks(ev, bool );
  1181. //                            ODReleaseObject( ev, window );
  1182.                         }
  1183.                     }
  1184.                     break;
  1185.         
  1186.                 case pIcon:
  1187.                     error = AECoerceDesc( &dataDesc, typeAERecord, &coercedDataDesc );
  1188.                     if ( !error )
  1189.                     {
  1190.                         ODIconFamily iconFamily = IfamToIconSuite(&coercedDataDesc);
  1191.                         ODSetIconFamily(ev, frame, iconFamily );
  1192.                         (void) DisposeIconSuite( iconFamily, kODTrue );
  1193.                     }
  1194.                     break;
  1195.     
  1196.                 case pViewType:
  1197.                     error = AECoerceDesc( &dataDesc, typeEnumeration,
  1198.                             &coercedDataDesc );
  1199.                     if ( !error )
  1200.                     {
  1201.                         DescType viewEnum = FIRSTBYTESFROMHANDLE(
  1202.                                 coercedDataDesc.dataHandle,    ODTypeToken );
  1203.                         ODTypeToken viewType = GetViewTypeFromEnum( ev, session,
  1204.                                 viewEnum );
  1205.                         PukeIfFrameNULL( frame );
  1206.                         frame->SetViewType( ev, viewType );
  1207.                     }
  1208.                     break;
  1209.     
  1210.                 case pEditorName:
  1211.                     error = AECoerceDesc(&dataDesc, typeIntlText, &coercedDataDesc);
  1212.                     if ( !error )
  1213.                     {
  1214.                         ODEditor editor;
  1215.                         error = GetEditorFromString(ev, &editor, &coercedDataDesc,
  1216.                                 thePart, session->GetNameSpaceManager(ev) );
  1217.                         TempODEditor tempEditor = ((ODPartWrapper*)thePart)->GetEditor(ev);
  1218.                         if ( (!error) &&
  1219.                             // don't try to set the same editor again....
  1220.                             strcmp(editor,tempEditor))
  1221.                         {
  1222.                             // <eeh> note that other code calling UseEditor
  1223.                             // mucks with the storage unit, perhaps to make
  1224.                             // the change stick?  Check this out.
  1225.                                ((ODPartWrapper*)thePart)->UseEditor( ev, editor );
  1226.                            }
  1227.                     }
  1228.                     break;
  1229.     
  1230.                 default:
  1231.                     error = errAEEventNotHandled;
  1232.             }
  1233.             AEDisposeDesc( &coercedDataDesc );
  1234.             AEDisposeDesc( &dataDesc );
  1235.         }
  1236.     }
  1237.  
  1238.     return error;
  1239. }    // HandleSetData()
  1240.  
  1241. /*******************************************************************************
  1242. //
  1243. // Utility functions
  1244. //
  1245. *******************************************************************************/
  1246.  
  1247. //------------------------------------------------------------------------------
  1248. // PutOneIcon
  1249. //------------------------------------------------------------------------------
  1250.  
  1251. static void PutOneIcon( Handle iconSuite, AERecord* ifam, DescType type )
  1252. {
  1253.     Handle iconData;
  1254.     OSErr err = GetIconFromSuite( &iconData, iconSuite, type);
  1255.     if ( err == noErr )
  1256.     {
  1257.         AEDesc oneIcon;
  1258.         oneIcon.descriptorType = type;
  1259.         oneIcon.dataHandle = iconData;
  1260.         err = AEPutKeyDesc( ifam, type, &oneIcon );
  1261.     }
  1262. }
  1263.  
  1264. //------------------------------------------------------------------------------
  1265. // IconSuiteToIfam
  1266. //------------------------------------------------------------------------------
  1267.  
  1268. static ODError IconSuiteToIfam( Handle iconSuite, AEDesc* result )
  1269. {
  1270.     if ( !iconSuite )
  1271.         return errAEEventFailed;    // need a better error?
  1272.     AERecord record;
  1273.     ODError err = AECreateList( kODNULL, 0, kODTrue, &record );
  1274.     if ( err ) return err ;
  1275.  
  1276.     PutOneIcon( iconSuite, &record, large1BitMask );        // 'ICN#',
  1277.     PutOneIcon( iconSuite, &record, large4BitData );        // 'icl4',
  1278.     PutOneIcon( iconSuite, &record, large8BitData );        // 'icl8',
  1279.     PutOneIcon( iconSuite, &record, small1BitMask );        // 'ics#',
  1280.     PutOneIcon( iconSuite, &record, small4BitData );        // 'ics4',
  1281.     PutOneIcon( iconSuite, &record, small8BitData );        // 'ics8',
  1282.     PutOneIcon( iconSuite, &record, mini1BitMask );            // 'icm#',
  1283.     PutOneIcon( iconSuite, &record, mini4BitData );            // 'icm4',
  1284.     PutOneIcon( iconSuite, &record, mini8BitData );            // 'icm8'
  1285.     
  1286.     err = AECoerceDesc( &record, 'ifam', result );
  1287.     AEDisposeDesc( &record );
  1288.     return err;
  1289. }
  1290.  
  1291. //------------------------------------------------------------------------------
  1292. // GetOneIcon
  1293. //------------------------------------------------------------------------------
  1294.  
  1295. static void GetOneIcon( Handle iconSuite, AERecord* ifam, DescType type )
  1296. {
  1297.     AEDesc oneIcon;
  1298.     ODError err = AEGetKeyDesc( ifam, type, type, &oneIcon );
  1299.     if ( !err )
  1300.     {
  1301.         if ( AddIconToSuite( oneIcon.dataHandle, iconSuite, type) != noErr )
  1302.             // no point in holding onto the handle
  1303.             AEDisposeDesc( &oneIcon );
  1304.     }
  1305. }
  1306.  
  1307. //------------------------------------------------------------------------------
  1308. // IfamToIconSuite
  1309. //------------------------------------------------------------------------------
  1310.  
  1311. static ODIconFamily IfamToIconSuite(AERecord* ifam)
  1312. {
  1313.     Handle iconSuite;
  1314.     OSErr err = NewIconSuite( &iconSuite );
  1315.     if ( err ) return kODNULL;
  1316.  
  1317.     GetOneIcon( iconSuite, ifam, large1BitMask );        // 'ICN#',
  1318.     GetOneIcon( iconSuite, ifam, large4BitData );        // 'icl4',
  1319.     GetOneIcon( iconSuite, ifam, large8BitData );        // 'icl8',
  1320.     GetOneIcon( iconSuite, ifam, small1BitMask );        // 'ics#',
  1321.     GetOneIcon( iconSuite, ifam, small4BitData );        // 'ics4',
  1322.     GetOneIcon( iconSuite, ifam, small8BitData );        // 'ics8',
  1323.     GetOneIcon( iconSuite, ifam, mini1BitMask );        // 'icm#',
  1324.     GetOneIcon( iconSuite, ifam, mini4BitData );        // 'icm4',
  1325.     GetOneIcon( iconSuite, ifam, mini8BitData );        // 'icm8'
  1326.  
  1327.     return iconSuite;
  1328. }
  1329.  
  1330. //------------------------------------------------------------------------------
  1331. // GetEditorFromString
  1332. //------------------------------------------------------------------------------
  1333.  
  1334. static ODError GetEditorFromString(Environment* ev, ODEditor* editor, AEDesc* desc, ODPart* part,
  1335.         ODNameSpaceManager* nsm )
  1336. {
  1337.     ODError error = errAEEventNotHandled;
  1338.     TempODIText newEditor = ITextFromIntlDesc( desc );
  1339.     if ( !newEditor ) return errAEEventNotHandled;
  1340.  
  1341.     EditorSet* editorSet = new EditorSet();
  1342.     editorSet->InitEditorSet();
  1343.     ODBoolean someFound = GetAllEditorsForKind( nsm, ODGetKind(ev, part ),
  1344.             editorSet );
  1345.  
  1346.     if ( someFound )
  1347.     {
  1348.         EditorSetIterator* editorIter = editorSet->CreateIterator();
  1349.         for (ODEditor candidate = editorIter->First();
  1350.             editorIter->IsNotComplete();
  1351.             candidate = editorIter->Next())
  1352.         {
  1353.             ODName* name;
  1354.             if ( GetUserEditorFromEditor( nsm, candidate, &name ) )
  1355.             {
  1356.                 if ( (GetITextStringLength(name) == GetITextStringLength(newEditor))
  1357.                     && (GetITextLangCode(name) == GetITextLangCode(newEditor))
  1358.                     && (GetITextScriptCode(name) == GetITextScriptCode(newEditor))
  1359.                     && strncmp(GetITextPtr(name),
  1360.                             GetITextPtr(newEditor), GetITextStringLength(name)) == 0 )
  1361.                 {
  1362.                     *editor = candidate;
  1363.                     error = noErr;
  1364.                     break;
  1365.                 }
  1366.             }
  1367.         }
  1368.         delete editorIter;
  1369.     }
  1370.     ODDeleteObject( editorSet );
  1371. //    DisposeIText(newEditor);
  1372.     return error;
  1373. }
  1374.  
  1375. //------------------------------------------------------------------------------
  1376. // ITextFromIntlDesc
  1377. //------------------------------------------------------------------------------
  1378.  
  1379. static ODIText* ITextFromIntlDesc( AEDesc* desc )
  1380. {
  1381.     WASSERT( desc->descriptorType == typeIntlText );
  1382.  
  1383.     ODSLong len = GetHandleSize( desc->dataHandle );
  1384.     ODLockHandle( desc->dataHandle );
  1385.     IntlText* ASItext = (IntlText*)*desc->dataHandle;
  1386.     // save as we're about to overwrite with stringlength byte
  1387.     ScriptCode scriptCode = ASItext->theScriptCode;
  1388.     LangCode langCode = ASItext->theLangCode;
  1389.     char* str = ((char*)&ASItext->theText) - 1 ;
  1390.     len -= sizeof(ASItext->theScriptCode)
  1391.                 + sizeof(ASItext->theScriptCode);
  1392.     str[0] = len;
  1393.     ODIText* name = CreateIText( scriptCode, langCode,
  1394.             (StringPtr)str );
  1395.     ODUnlockHandle( desc->dataHandle );
  1396.     return name;
  1397. }
  1398.  
  1399. //------------------------------------------------------------------------------
  1400. // ViewTypetoViewEnum
  1401. //------------------------------------------------------------------------------
  1402.  
  1403. static DescType ViewTypetoViewEnum( Environment *ev, ODSession* session,
  1404.         ODTypeToken viewType )
  1405. {
  1406.     if ( viewType == session->Tokenize(ev, kODViewAsSmallIcon) )
  1407.         return kAEODSmallIcon;
  1408.     else if ( viewType == session->Tokenize(ev, kODViewAsLargeIcon) )
  1409.         return kAEODLargeIcon;
  1410.     else if ( viewType == session->Tokenize(ev, kODViewAsFrame) )
  1411.         return kAEODFrame;
  1412.     else if ( viewType == session->Tokenize(ev, kODViewAsThumbnail) )
  1413.         return kAEODThumbnail;
  1414.     else
  1415.     {
  1416.         WARN( "ViewTypetoViewEnum found unknown viewType" );
  1417.         return typeNull;
  1418.     }
  1419. }
  1420.  
  1421. //------------------------------------------------------------------------------
  1422. // GetViewTypeFromEnum
  1423. //------------------------------------------------------------------------------
  1424.  
  1425. static ODTypeToken GetViewTypeFromEnum( Environment *ev, ODSession* session,
  1426.         DescType viewEnum )
  1427. {
  1428.     switch( viewEnum )
  1429.     {
  1430.         case kAEODSmallIcon:
  1431.             return session->Tokenize(ev, kODViewAsSmallIcon);
  1432.         case kAEODLargeIcon:
  1433.             return session->Tokenize(ev, kODViewAsLargeIcon);
  1434.         case kAEODFrame:
  1435.             return session->Tokenize(ev, kODViewAsFrame);
  1436.         case kAEODThumbnail:
  1437.             return session->Tokenize(ev, kODViewAsThumbnail);
  1438.         default:
  1439.             WARN( "GetViewTypeFromEnum: unknown view type enum" );
  1440.             return -1;
  1441.     }    
  1442. }
  1443.  
  1444. //------------------------------------------------------------------------------
  1445. // GetDirectParam
  1446. //
  1447. //    WE NEED TO CONSOLIDATE THIS WITH GetDirectParam IN RlShlEv.cpp!
  1448. //------------------------------------------------------------------------------
  1449.  
  1450. static void GetDirectParam(ODSession* session, ODAppleEvent* message,
  1451.         AEDesc* evtDp)
  1452. {
  1453.     Environment* ev = somGetGlobalEnvironment();
  1454.     AppleEvent localAEVT;
  1455.     THROW_IF_ERROR( ODDescToAEDesc( message, &localAEVT ) );
  1456.  
  1457.     AEDesc localDP;
  1458.     THROW_IF_ERROR( AEGetParamDesc( &localAEVT, keyDirectObject,
  1459.             typeWildCard, &localDP ) );
  1460.     ODOSLToken* oddesc = new ODOSLToken();
  1461.     THROW_IF_NULL(oddesc);
  1462.     oddesc->InitODOSLToken(ev);
  1463.     THROW_IF_ERROR( AEDescToODDesc( &localDP, oddesc ) );
  1464.  
  1465.     ODNameResolver* resolver = session->GetNameResolver(ev);
  1466.     ODBoolean isToken = resolver->IsODToken(ev, oddesc);
  1467.     ODDeleteObject(oddesc);
  1468.     if ( isToken )
  1469.     {
  1470.         *evtDp = localDP;
  1471.     }
  1472.     else
  1473.     {
  1474.         (void)AEDisposeDesc( &localDP );
  1475.         WARN("GetDirectParam. Found a non-token.  About to throw.");
  1476.         THROW( errAEEventNotHandled );
  1477.     }
  1478.     
  1479.     ODDisposeAppleEvent(&localAEVT);
  1480. }    // GetDirectParam()
  1481.  
  1482. //------------------------------------------------------------------------------
  1483. // DescToODOSLToken
  1484. //------------------------------------------------------------------------------
  1485.  
  1486. static ODOSLToken* DescToODOSLToken( Environment* ev, ODNameResolver* resolver,
  1487.         AEDesc* frameDesc, ODOSLToken* tokenToCopy )
  1488. {
  1489.     ODOSLToken* newToken = tokenToCopy->DuplicateODOSLToken(ev);
  1490.     ODDesc* userODToken = resolver->GetUserToken( ev, newToken );
  1491.     AEDescToODDesc(frameDesc, userODToken);
  1492.  
  1493.     return newToken;
  1494. }
  1495.  
  1496. //------------------------------------------------------------------------------
  1497. // AddODOSLTokenToList
  1498. //
  1499. //    Add newToken into list that's in value.
  1500. //------------------------------------------------------------------------------
  1501.  
  1502. static void AddODOSLTokenToList( ODOSLToken* newToken, ODUShort index,
  1503.         AEDesc* list )
  1504. {
  1505.     AEDesc singleTokenAsAEDesc;
  1506.     THROW_IF_ERROR( ODDescToAEDesc( newToken, &singleTokenAsAEDesc ) );
  1507.     
  1508.     WASSERT( list->descriptorType == typeAEList );
  1509.  
  1510.     THROW_IF_ERROR( AEPutDesc( list, index, &singleTokenAsAEDesc) );
  1511.     (void)AEDisposeDesc( &singleTokenAsAEDesc );
  1512. }
  1513.  
  1514.  
  1515. //------------------------------------------------------------------------------
  1516. // PutFrameInValue
  1517. //------------------------------------------------------------------------------
  1518.  
  1519. static void PutFrameInValue( Environment* ev, ODNameResolver* resolver,
  1520.         ODOSLToken* value, ODFrame* frame )
  1521. {
  1522.     AEDesc    myToken;
  1523.  
  1524.     if ( !frame )
  1525.         THROW(errAENoSuchObject);
  1526.     TempODPart part = frame->AcquirePart(ev);
  1527.     CreateStandardPartToken( frame, part, &myToken );
  1528.     ODDesc* userODToken = resolver->GetUserToken(ev, value);
  1529.     THROW_IF_ERROR( AEDescToODDesc( &myToken, userODToken ));
  1530.     AEDisposeDesc(&myToken);
  1531. }
  1532.  
  1533. //------------------------------------------------------------------------------
  1534. // ITextEqual
  1535. //------------------------------------------------------------------------------
  1536.  
  1537. static ODBoolean ITextEqual( ODIText* name1, ODIText* name2 )
  1538. {
  1539.     return ( (GetITextLangCode(name1) == GetITextLangCode(name2))
  1540.         && (GetITextScriptCode(name1) == GetITextScriptCode(name2))
  1541.         && (GetITextStringLength(name1) == GetITextStringLength(name2))
  1542.         && (strcmp( GetITextString(name1, (char*)kODNULL),
  1543.                 GetITextString(name2, (char*)kODNULL))==0) ) ;
  1544. }
  1545.  
  1546. //------------------------------------------------------------------------------
  1547. // AcquireFrameWithName
  1548. //------------------------------------------------------------------------------
  1549. static ODFrame* AcquireFrameWithName( Environment* ev, ODFrame* startFrame,
  1550.         ODIText* name )
  1551. {
  1552.     // beginning with this part, or with root part if this part is null,
  1553.     // do a recursive search until we find a part whose name is the same
  1554.     // as that given by name.  It's important to always begin the search
  1555.     // with this part, as we shouldn't find a part with the target name if
  1556.     // it isn't inside our container.
  1557.  
  1558.     ODBoolean                    foundNonEmbeddingFrame = kODFalse;
  1559.     ODEmbeddedFramesIterator*    iter;
  1560.  
  1561.     ODVolatile(foundNonEmbeddingFrame);
  1562.  
  1563.     WASSERT( startFrame );
  1564.  
  1565.     TempODPart savePart = startFrame->AcquirePart(ev);
  1566.     TRY
  1567.         iter = savePart->CreateEmbeddedFramesIterator(ev, kODNULL);
  1568.         if (iter == kODNULL)
  1569.             foundNonEmbeddingFrame = kODTrue;
  1570.     CATCH_ALL
  1571.         foundNonEmbeddingFrame = kODTrue;
  1572.     ENDTRY
  1573.  
  1574.     ODFrame* result = kODNULL;
  1575.     
  1576.     if (!foundNonEmbeddingFrame)
  1577.     {
  1578.         ODFrame* frame;
  1579.         for ( frame = iter->First(ev); iter->IsNotComplete(ev);
  1580.                                 frame = iter->Next(ev) )
  1581.         {
  1582.             TempODIText canName = ODGetPartName(ev, frame, kODNULL );
  1583.             if ( ITextEqual( canName, name ) )
  1584.             {
  1585.                 frame->Acquire(ev);
  1586.                 result = frame;
  1587.                 break;
  1588.             }
  1589.             else if ( (result = AcquireFrameWithName( ev, frame, name )) != kODNULL )
  1590.                 break;
  1591.         }
  1592.         ODDeleteObject(iter);
  1593.     }
  1594.  
  1595.     return result;
  1596. }
  1597.  
  1598. //------------------------------------------------------------------------------
  1599. // CreateObjSpecForFrame
  1600. //------------------------------------------------------------------------------
  1601.  
  1602. static OSErr CreateObjSpecForFrame( Environment *ev, ODFrame* frame,
  1603.         AEDesc* result )
  1604. {
  1605.     ODPersistentObjectID id = GetIDForFrame( ev, frame );
  1606.     AEDesc nullDesc = NULL_DESCRIPTOR_DEFINITION;
  1607.     AEDesc dataDesc;
  1608.     THROW_IF_ERROR( AECreateDesc( typeLongInteger, &id, sizeof(id),
  1609.             &dataDesc ) );
  1610.     return CreateObjSpecifier( cPart, &nullDesc, pUniqueID,
  1611.             &dataDesc, true, result );
  1612. }
  1613.  
  1614. //------------------------------------------------------------------------------
  1615. // GetIDForFrame
  1616. //------------------------------------------------------------------------------
  1617.  
  1618. static ODPersistentObjectID GetIDForFrame( Environment* ev, ODFrame* frame )
  1619. {
  1620.     ODStorageUnit* su = frame->GetStorageUnit(ev);
  1621.     WASSERT(su);
  1622.     ODDraft* draft = su->GetDraft(ev);
  1623.     WASSERT(draft);
  1624.     return draft->GetPersistentObjectID( ev,
  1625.             (ODPersistentObject*)frame, kODFrameObject);
  1626. }
  1627.  
  1628. //------------------------------------------------------------------------------
  1629. // CopyNonDPParams
  1630. // Move from one AppleEvent to another all parameters but the direct parameter.
  1631. // <eeh> should modify to move attributes as well, probably by changing the
  1632. // type of the AppleEvent from 'aevt' to 'meta' temporarily.  This function
  1633. // could then also be used in ODMessageInterface::DispatchToEventHandlerAux
  1634. // where it copies data back into the reply it must return.
  1635. //------------------------------------------------------------------------------
  1636.  
  1637. #ifdef TO_BE_DELETED
  1638. static void CopyNonDPParams( ODAppleEvent* message, ODAppleEvent* newMessage )
  1639. {
  1640.     AppleEvent sourceAEVT;
  1641.     AppleEvent destAEVT;
  1642.     THROW_IF_ERROR( ODDescToAEDesc( message, &sourceAEVT ) );
  1643.     THROW_IF_ERROR( ODDescToAEDesc( newMessage, &destAEVT ) );
  1644.  
  1645.     long numParams;
  1646.     THROW_IF_ERROR( AECountItems( &sourceAEVT, &numParams ) );
  1647.     for ( long index = 1; index <= numParams; ++index )
  1648.     {
  1649.         AEDesc oneParam;
  1650.         DescType keyword;
  1651.         THROW_IF_ERROR( AEGetNthDesc( &sourceAEVT, index, typeWildCard,
  1652.                 &keyword, &oneParam ) );
  1653.         if ( keyword != keyDirectObject )
  1654.             THROW_IF_ERROR( AEPutParamDesc( &destAEVT, keyword, &oneParam ) );
  1655.         AEDisposeDesc( &oneParam );
  1656.     }
  1657.     THROW_IF_ERROR( AEDescToODDesc( &destAEVT, newMessage ) );
  1658.     ODDisposeAppleEvent( &sourceAEVT );
  1659.     ODDisposeAppleEvent( &destAEVT );
  1660. }
  1661. #endif /* TO_BE_DELETED */
  1662.  
  1663. //------------------------------------------------------------------------------
  1664. // PartIsContained
  1665. //------------------------------------------------------------------------------
  1666.  
  1667. ODBoolean PartIsContained( Environment* ev, ODFrame* testee,
  1668.     ODFrame* container )
  1669. {
  1670.     ODBoolean result ;
  1671.     if ( !testee )
  1672.          result = kODFalse;
  1673.     else if ( !container )
  1674.         result = kODTrue;        // root frame contains all
  1675.  
  1676.     // before the first AcquireContainingFrame call don't test for equality,
  1677.     // as a frame can't contain itself.
  1678.     else
  1679.     {
  1680.         while ( !result &&
  1681.                 ((testee = testee->AcquireContainingFrame(ev)) != kODNULL) )
  1682.         {
  1683.             result = ODObjectsAreEqual( ev, testee, container );
  1684.             ODFrame* saveCopy = testee;
  1685.             ODReleaseObject( ev, saveCopy );
  1686.         }
  1687.     }
  1688.     return result;
  1689. }
  1690.  
  1691. //------------------------------------------------------------------------------
  1692. // IndexForFrame
  1693. //------------------------------------------------------------------------------
  1694.  
  1695. static OSErr IndexForFrame( Environment *ev, ODFrame* frame, ODULong* result )
  1696. {
  1697.     TempODFrame parentFrame = frame->AcquireContainingFrame(ev);
  1698.     ODULong tempResult = 0;
  1699.     if ( parentFrame != kODNULL )
  1700.     {
  1701.         TempODPart part = parentFrame->AcquirePart(ev);
  1702.         ODEmbeddedFramesIterator* iter =
  1703.                 part->CreateEmbeddedFramesIterator( ev, kODNULL );
  1704.         if (iter == kODNULL)
  1705.             THROW(kODErrCannotEmbed);
  1706.         ODFrame* testFrame;
  1707.         for ( testFrame = iter->First(ev), tempResult = 1;
  1708.                 !ODObjectsAreEqual(ev, frame, testFrame)
  1709.                         && iter->IsNotComplete(ev);
  1710.                 ++tempResult, testFrame = iter->Next(ev) )
  1711.         {
  1712.         }
  1713.         ODDeleteObject(iter);
  1714.     }
  1715.     else
  1716.     {
  1717.         return errAENoSuchObject;
  1718.     }
  1719.     *result = tempResult;
  1720.     return noErr;
  1721. }
  1722.  
  1723. //------------------------------------------------------------------------------
  1724. // SwapToRootPart
  1725. //------------------------------------------------------------------------------
  1726.  
  1727. static ODError SwapToRootPart( Environment *ev, ODSession* session,
  1728.         ODOSLToken* value)
  1729. {
  1730.     ODFrame* frame = GetDefaultRootFrameToSwapTo(ev, session);
  1731.     if ( !frame )
  1732.         return errAENoSuchObject;
  1733.     else
  1734.     {
  1735.         // when will this part be released???
  1736.         TempODPart savePart = frame->AcquirePart(ev);
  1737.         session->GetNameResolver(ev)->
  1738.                 CreateSwapToken( ev, value, savePart, frame );
  1739. //        ODReleaseObject( ev, savePart );
  1740.     }
  1741.     return noErr;
  1742. }
  1743.  
  1744. //------------------------------------------------------------------------------
  1745. // ODDuplicateEvent
  1746. //------------------------------------------------------------------------------
  1747.  
  1748. void ODDuplicateEvent( ODAppleEvent* scrDesc,
  1749.         ODAppleEvent** destDesc )
  1750. {
  1751.     Environment*    ev = somGetGlobalEnvironment();
  1752.     AppleEvent newAevt;
  1753.     OSErr err = ODDescToAEDesc( scrDesc, &newAevt );
  1754.     if ( err == noErr )
  1755.     {
  1756.         ODAppleEvent* tmp = new ODAppleEvent();
  1757.         THROW_IF_NULL(tmp);
  1758.         tmp->InitODAppleEvent(ev);
  1759.         err = AEDescToODDesc( &newAevt, tmp );
  1760.         ODDisposeAppleEvent(&newAevt);
  1761.         *destDesc = tmp;
  1762.     }
  1763.     THROW_IF_ERROR(err);
  1764. }
  1765.  
  1766. //------------------------------------------------------------------------------
  1767. // ODPutParamDesc
  1768. //------------------------------------------------------------------------------
  1769.  
  1770. void ODPutParamDesc( ODAppleEvent* odaevt, DescType keyword, AEDesc* desc )
  1771. {
  1772.     AppleEvent local;
  1773.     OSErr err = ODDescToAEDesc( odaevt, &local );
  1774.     if ( err == noErr )
  1775.     {
  1776.         err = AEPutParamDesc( &local, keyword, desc );
  1777.         if ( err == noErr )
  1778.             err = AEDescToODDesc( &local, odaevt );
  1779.         ODDisposeAppleEvent(&local);
  1780.     }
  1781.     THROW_IF_ERROR(err);
  1782. }
  1783.  
  1784. //------------------------------------------------------------------------------
  1785. // ODPutParamDesc
  1786. //------------------------------------------------------------------------------
  1787.  
  1788. void ODPutParamDesc( ODAppleEvent* odaevt, DescType keyword, ODDesc* desc )
  1789. {
  1790.     AEDesc localDesc;
  1791.     THROW_IF_ERROR( ODDescToAEDesc( desc, &localDesc ) );
  1792.     TempAEDesc tmpDesc(&localDesc);
  1793.     ODPutParamDesc( odaevt, keyword, &localDesc );
  1794. }
  1795.  
  1796. //------------------------------------------------------------------------------
  1797. // ODGetParamDesc
  1798. //------------------------------------------------------------------------------
  1799.  
  1800. void ODGetParamDesc( ODAppleEvent* odaevt, DescType keyword, DescType typeSought,
  1801.         AEDesc* desc )
  1802. {
  1803.     AppleEvent event;
  1804.     OSErr err = ODDescToAEDesc( odaevt, &event );
  1805.     if ( err == noErr )
  1806.     {
  1807.         err = AEGetParamDesc( &event, keyword, typeSought, desc );
  1808.         ODDisposeAppleEvent(&event);
  1809.     }
  1810.     THROW_IF_ERROR(err);
  1811. }
  1812.  
  1813. //------------------------------------------------------------------------------
  1814. // ODGetParamDesc
  1815. //------------------------------------------------------------------------------
  1816.  
  1817. void ODGetParamDesc( ODAppleEvent* odaevt, DescType keyword,
  1818.         DescType typeSought, ODDesc** desc )
  1819. {
  1820.     Environment*    ev = somGetGlobalEnvironment();
  1821.     AEDesc            resultAsAEDesc;
  1822.  
  1823.     ODDesc* result = new ODDesc();
  1824.     THROW_IF_NULL(result);
  1825.     result->InitODDesc( ev );
  1826.  
  1827.     ODGetParamDesc( odaevt, keyword, typeSought, &resultAsAEDesc );
  1828.     OSErr error = AEDescToODDesc( &resultAsAEDesc, result);
  1829.     THROW_IF_ERROR (error);
  1830.     AEDisposeDesc(&resultAsAEDesc);
  1831.     *desc = result;
  1832. }
  1833.  
  1834. //------------------------------------------------------------------------------
  1835. // ODPutAttributeDesc
  1836. //------------------------------------------------------------------------------
  1837.  
  1838. void ODPutAttributeDesc( ODAppleEvent* message, AEKeyword key, ODDesc* desc )
  1839. {
  1840.     AppleEvent messageAsAEDesc;
  1841.     THROW_IF_ERROR( ODDescToAEDesc( message, &messageAsAEDesc ) );
  1842.     AEDesc attrDescAsAEDesc;
  1843.     THROW_IF_ERROR( ODDescToAEDesc( desc, &attrDescAsAEDesc ) );
  1844.     THROW_IF_ERROR( AEPutAttributeDesc( &messageAsAEDesc, key,
  1845.                                         &attrDescAsAEDesc) );
  1846.     AEDisposeDesc(&attrDescAsAEDesc);
  1847.     THROW_IF_ERROR( AEDescToODDesc(&messageAsAEDesc, message ));
  1848.     ODDisposeAppleEvent(&messageAsAEDesc);
  1849. }
  1850.  
  1851. //------------------------------------------------------------------------------
  1852. // ODGetAttributePtr
  1853. //------------------------------------------------------------------------------
  1854.  
  1855. void ODGetAttributePtr( ODAppleEvent *appleEvent, AEKeyword theAEKeyword,
  1856.         DescType desiredType, DescType *typeCode, void *dataPtr,
  1857.         Size maximumSize, Size *actualSize)
  1858. {
  1859.     AppleEvent event;
  1860.     OSErr err = ODDescToAEDesc( appleEvent, &event );
  1861.     if ( err == noErr )
  1862.     {
  1863.         err = AEGetAttributePtr( &event, theAEKeyword, desiredType,
  1864.                 typeCode, dataPtr, maximumSize, actualSize );
  1865.         (void)ODDisposeAppleEvent( &event );
  1866.     }
  1867.     THROW_IF_ERROR( err );
  1868. }
  1869.  
  1870. #if ODDebug
  1871. void ASSERT_FRAME_MATCHES_PART( Environment *ev, ODFrame* frame, ODPart* part )
  1872. {
  1873. #if 0
  1874.     if ( frame )
  1875.     {
  1876.         TempODPart savePart = frame->AcquirePart(ev);
  1877.         ODBoolean partMatchesFrame = ODObjectsAreEqual(ev, savePart, part);
  1878. //        ODBoolean partMatchesFrame = savePart == part;
  1879. //        ODReleaseObject( ev, savePart );
  1880.         WASSERT( partMatchesFrame );
  1881.     }
  1882. #endif
  1883. }
  1884. #endif
  1885.  
  1886.